package com.nulldev.util.web.HttpClient;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.io.extensions.copyable.ClosingCopyable;
import com.nulldev.util.io.extensions.copyable.nio.ClosingNIOCopyable;
import com.nulldev.util.io.extensions.copyable2.ClosingCopyable2;
import com.nulldev.util.web.HttpClient.util.HttpClientUtil;

public interface HttpResponse<T> extends AutoCloseable, ClosingCopyable, ClosingNIOCopyable, ClosingCopyable2 {

	public int status();

	public boolean successful();

	public ResponseFormat format();

	public T data();

	public T data(final boolean avoidDecoding);

	public T dataThenClose();

	public T dataThenClose(final boolean avoidDecoding);

	public Map<String, List<String>> headers();

	public String[] cookies();

	public default List<String> cookiesAsList() {
		return Arrays.asList(this.cookies());
	}

	/**
	 * Attempts to close the connection if Keep-Alive is not sent.
	 * 
	 * @on-unsupported Will invoke close().
	 * @throws Exception
	 */
	public void adaptiveClose() throws Exception;

	/**
	 * Gets the length of the stream.
	 * 
	 * @returns -1 if not found or compressed.
	 */
	public default long length() {
		return length(false);
	}

	/**
	 * Gets the length of the stream.
	 * 
	 * @param raw - If true, a Content-Length will be returned even if the response
	 *            is compressed.
	 * @returns -1 if not found. (or compressed if raw is false)
	 */
	public default long length(final boolean raw) {
		if (raw) {
			return HttpClientUtil.getRawFallbackLength(this);
		} else {
			return HttpClientUtil.getFallbackLength(this);
		}
	}

	public default String getHeaderField(String string) {
		if (string == null || string.isEmpty())
			return null;
		if (!this.headers().containsKey(string))
			return null;
		return StringsUtil.join(this.headers().get(string), ";");
	}

	public default Version transportVersion() {
		return null;
	}
}
